<template>
    <div ref="refBar" class="bar" v-observe-visibility="onShow">
        <div ref="refHandle" class="handle" :title="value.toString()"></div>
    </div>
</template>

<style scoped>
.bar {
    border-color: rgb(120, 120, 120);
    border-width: 1px;
    border-style: solid;
    border-radius: 22px;
    background-image: linear-gradient(to right, #333, #FF0000);
}
.handle {
    width: 36px ;
    height: 36px ;
    border-radius: 21px;
    border-color: #fff;
    border-width: 3px;
    border-style: solid;
    margin: 1px;
}
</style>

<script lang="ts" setup>
import { ref, onMounted, Ref, watch, nextTick } from 'vue';
import debouncer from '../../base/debouncer';

const props = defineProps<{
    value: number ,
}>()
const emit = defineEmits(["update:value"])
let emittingUpdateValue = false

let color = [255,0,0]

let raw = 1
let maxValue = 0

let $bar: any
const refBar = ref(null) as unknown as Ref<HTMLElement>

let $handle: any
const refHandle = ref(null) as unknown as Ref<HTMLElement>

defineExpose({setColor})

onMounted (()=>{
    $bar = $(refBar.value)
    $handle = $(refHandle.value)

    $handle.draggable({
        containment: $bar
        , drag: debouncer((event: any, ui: any)=>{
            raw = ui.position.left/maxValue
            onRawChanged()
            emittingUpdateValue = true
            emit("update:value", Math.round(255*raw))
        }, 10)
        , start: ()=>{
            maxValue = calculateMaxValue()
        }
        , axis: "x"
    })

    maxValue = calculateMaxValue()
    setHandlePosWithValue()
})

function setHandlePosWithValue() {
    let left = Math.round(maxValue*(props.value/255))
    $handle.css("left", left+'px')
}

function calculateMaxValue() {
    // console.log("calculateMaxValue", $bar.innerWidth())
    let max = $bar.innerWidth() - $handle.outerWidth() - 2
    if(max<0) 
        max = 0
    return max
}

watch(()=>props.value, (newValue:number)=>{
    if(emittingUpdateValue) {
        emittingUpdateValue = false
        return
    }
    raw = newValue/255
    onRawChanged()
    setHandlePosWithValue()
})
// watch(color, setColor)

function setColor(newColor: number[]) {
    color = newColor
    $bar.css('background-image', `linear-gradient(to right, #333, rgb(${color[0]},${color[1]},${color[2]})`)
    onRawChanged()
}

function onRawChanged() {
    let r = Math.ceil(color[0] * raw)
    let g = Math.ceil(color[1] * raw)
    let b = Math.ceil(color[2] * raw)
    $handle.css('background-color', `rgb(${r},${g},${b})`)
}

function onShow() {
    maxValue = calculateMaxValue()
    setHandlePosWithValue()
}

</script>